﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="LazyInitializer.cs" company="JDML Consulting Ltd.">
//   Copyright 2011 Photon Project - http://photon.codeplex.com
// </copyright>
// <summary>
//   Defines the LazyInitializer type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Photon.Threading
{
    using System;
    using System.Threading;

    public static class LazyInitializer
    {
        public static T EnsureInitialized<T>(ref T location, Func<T> valueFactory) where T : class
        {
            T result;
            EnsureInitialized(ref location, valueFactory, out result);
            return result;
        }

        public static bool EnsureInitialized<T>(ref T location, Func<T> valueFactory, out T result) where T : class
        {
            result = location;
            if (result != null)
            {
                return false;
            }

            var initialized = false;
            var value = valueFactory();
            try
            {
                initialized = (result = Interlocked.CompareExchange(ref location, value, null)) == null;
                if (initialized)
                {
                    result = value;
                }
            }
            finally
            {
                if (!initialized)
                {
                    var disposableValue = value as IDisposable;
                    if (disposableValue != null)
                    {
                        disposableValue.Dispose();
                    }
                }
            }
            
            return initialized;
        }
    }
}
